﻿using System;
using System.Windows.Forms;
using DriveBeamEditor.Interfaces;
using DriveBeamEditor.Tools;
using JBeamLibrary.Types;

namespace DriveBeamEditor.Controls.General
{
    public partial class Editor : UserControl, IEditor
    {
        #region Fields

        private Control _editor;
        private object _editValue;

        public event EventHandler EditValueChanged;

        #endregion

        #region Properties

        public object EditValue
        {
            get { return _editValue; }
            set
            {
                if (_editValue == value) return;

                _editValue = value;

                OnEditValueChanged();
            }
        }

        public Control Control
        {
            get { return _editor; }
            internal set { _editor = value; }
        }

        #endregion

        #region CTORs

        public Editor()
        {
            InitializeComponent();
        }

        #endregion

        #region Methods

        private void UpdateEditor()
        {
            Controls.Clear();
            if (EditValue == null) return;

            var editor = EditValue == DBNull.Value && _editor != null ? _editor : UIHelper.GetEditor(EditValue.GetType());
            if (editor == null) return;

            editor.Dock = DockStyle.Fill;
            _editor = editor;

            UIHelper.SetValue(editor, EditValue);
            Controls.Add(editor);

            if (DesignMode) return;

            if (editor is TextBox)
                ((TextBox)editor).TextChanged += (s, e) => OnUserEditValue(((TextBox)editor).Text);
            else if (editor is NumericUpDown)
                ((NumericUpDown)editor).ValueChanged += (s, e) => OnUserEditValue(((NumericUpDown)editor).Value);
            else if (editor is CheckBox)
                ((CheckBox)editor).CheckedChanged += (s, e) => OnUserEditValue(((CheckBox)editor).Checked);
            else if (editor is ComboBox)
                ((ComboBox)editor).SelectedIndexChanged += (s, e) => OnUserEditValue(((ComboBox)editor).SelectedItem);
            else if (editor is Float3Edit)
                ((Float3Edit)editor).EditValueChanged += (s, e) => OnUserEditValue(((Float3Edit)editor).EditValue);
            else if (editor is NumEdit)
                ((NumEdit)editor).EditValueChanged += (s, e) => OnUserEditValue(((NumEdit)editor).EditValue);
            else if (editor is ColorEdit)
                ((ColorEdit) editor).EditValueChanged += (s, e) => OnUserEditValue(((ColorEdit) editor).EditValue);
        }

        public void SetEditValueSilent(object value)
        {
            _editValue = value;
            UpdateEditor();
        }

        private void OnUserEditValue(object value)
        {
            _editValue = value;

            if (EditValueChanged != null)
                EditValueChanged(this, new EventArgs());
        }

        private void OnEditValueChanged()
        {
            UpdateEditor();

            if (EditValueChanged != null)
                EditValueChanged(this, new EventArgs());
        }

        #endregion
    }
}
